package logger

import (
	"fmt"
	"gitee.com/hexug/vblog/tree/master/api/conf"
	"os"
	"strings"

	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

// 正常日志编码器
func GetFileEnCoder() zapcore.Encoder {
	config := zap.NewProductionEncoderConfig()
	config.EncodeTime = zapcore.ISO8601TimeEncoder
	config.EncodeLevel = zapcore.CapitalLevelEncoder
	config.EncodeDuration = zapcore.NanosDurationEncoder
	config.EncodeCaller = zapcore.ShortCallerEncoder
	config.EncodeName = zapcore.FullNameEncoder
	return zapcore.NewConsoleEncoder(config)
}

// 带颜色的日志编码器
func GetConsoleEnCoder() zapcore.Encoder {
	config := zap.NewProductionEncoderConfig()
	config.EncodeTime = zapcore.ISO8601TimeEncoder
	config.EncodeLevel = zapcore.CapitalColorLevelEncoder
	config.EncodeCaller = zapcore.ShortCallerEncoder
	return zapcore.NewConsoleEncoder(config)
}

// 生成普通信息的Writer
func GetInfoWriterSyncer(path string) zapcore.WriteSyncer {
	p := strings.TrimRight(path, `/`)
	//引入第三方库 Lumberjack 加入日志切割功能
	infoLumberIO := &lumberjack.Logger{
		Filename:   p + "/info.log",
		MaxSize:    10, // megabytes
		MaxBackups: 100,
		MaxAge:     28,    // days
		Compress:   false, //Compress确定是否应该使用gzip压缩已旋转的日志文件。默认值是不执行压缩。
	}
	return zapcore.AddSync(infoLumberIO)
}

// 生成故障信息的Writer
func GetErrorWriterSyncer(path string) zapcore.WriteSyncer {
	p := strings.TrimRight(path, `/`)
	//引入第三方库 Lumberjack 加入日志切割功能
	lumberWriteSyncer := &lumberjack.Logger{
		Filename:   p + "/error.log",
		MaxSize:    10, // megabytes
		MaxBackups: 100,
		MaxAge:     28,    // days
		Compress:   false, //Compress确定是否应该使用gzip压缩已旋转的日志文件。默认值是不执行压缩。
	}
	return zapcore.AddSync(lumberWriteSyncer)
}

var (
	logger *zap.SugaredLogger
)

func L() *zap.SugaredLogger {
	if logger == nil {
		logger = Logger()
	}
	return logger
}
func Logger() *zap.SugaredLogger {
	level := map[string]zapcore.Level{
		"debug": zapcore.DebugLevel,
		"info":  zapcore.InfoLevel,
		"warn":  zapcore.WarnLevel,
		"error": zapcore.ErrorLevel,
		"fatal": zapcore.FatalLevel,
		"panic": zapcore.PanicLevel,
	}
	p := conf.C().Log.SaveFileDir
	encoderfile := GetFileEnCoder()
	encoderconsole := GetConsoleEnCoder()
	infowriter := GetInfoWriterSyncer(p)
	errwriter := GetErrorWriterSyncer(p)

	infolevel := zap.LevelEnablerFunc(func(l zapcore.Level) bool {
		return l < zap.ErrorLevel && l >= zap.DebugLevel
	})
	errlevel := zap.LevelEnablerFunc(func(l zapcore.Level) bool {
		return l >= zap.ErrorLevel
	})
	infocore := zapcore.NewCore(encoderfile, infowriter, infolevel)
	errcore := zapcore.NewCore(encoderfile, errwriter, errlevel)
	consolecore := zapcore.NewCore(encoderconsole, zapcore.AddSync(os.Stdout), level[strings.ToLower(conf.C().Log.LogLevel)])
	core := []zapcore.Core{consolecore}
	if conf.C().Log.SaveFile {
		fmt.Println("日志写入文件")
		core = append(core, infocore)
		core = append(core, errcore)
	}
	logger := zap.New(zapcore.NewTee(core...), zap.AddCaller())
	return logger.Sugar()
}
